package com.ruoyi.app.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.app.annotation.AppSecurity;
import com.ruoyi.app.service.AppService;
import com.ruoyi.app.util.ReqMsg;
import com.ruoyi.app.util.RspMsg;
import com.ruoyi.bizsys.dto.PayTrans;
import com.ruoyi.bizsys.service.ICustBankCardService;
import com.ruoyi.bizsys.service.ILoanOrderErrorLogService;
import com.ruoyi.business.domain.AccountNumAuthReq;
import com.ruoyi.business.domain.CustAccount;
import com.ruoyi.business.domain.LoanReq;
import com.ruoyi.business.service.*;
import com.ruoyi.common.VersionUtils;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: Jamnsin
 * @Date: 2021/3/10 3:04 下午
 */
@Slf4j
@Api("贷款提现模块接口")
@RestController
@RequestMapping("/app/loan")
public class LoanController extends BaseController {

    @Autowired
    AppService appService;

    @Autowired
    ILoanService loanService;

    @Autowired
    QuickRepayService quickRepayService;

    @Autowired
    ILoanApplyService loanApplyService;

    @Autowired
    ICustVaService custVaService;

    @Autowired
    IPayTransService payTransService;

    @Autowired
    IBLoanInfoService loanInfoService;

    @Autowired
    ICustBankCardService custBankCardService;

    @Autowired
    IRaiseLimitService raiseLimitService;

    @Autowired
    private ILoanOrderErrorLogService loanOrderErrorLogService;

    @Autowired
    IBankCardService bankCardService;

    @AppSecurity
    @PostMapping("/check/account")
    @ApiOperation("校验银行帐户号")
    @Log(title = "校验银行帐户号", businessType = BusinessType.AUTH)
    public RspMsg checkAccountNumber(@RequestBody @Validated ReqMsg reqMsg) {

        AccountNumAuthReq accountNumAuthReq = JSON.parseObject(reqMsg.getData().toString(), AccountNumAuthReq.class);
        log.info("请求data：{}", JSON.toJSONString(accountNumAuthReq));

        checkAttribute(accountNumAuthReq);

        payTransService.checkAccountNumber(accountNumAuthReq.getAccountNumber(), accountNumAuthReq.getBankCode());

        return RspMsg.ok();
    }

    @AppSecurity
//    @RepeatSubmit
    @PostMapping("/apply")
    @ApiOperation("提现提交")
    @Log(title = "提现提交", businessType = BusinessType.SUBMIT)
    public RspMsg loanSumbit(@RequestBody @Validated ReqMsg reqMsg) {

        LoanReq loanReq = JSON.parseObject(reqMsg.getData().toString(), LoanReq.class);
        log.info("请求data：{}", JSON.toJSONString(loanReq));
        checkAttribute(loanReq);
        // 验证交易密码
        checkCustTransPwd(loanReq);

        // 小于 2.2.0 卡策略
        if (VersionUtils.compareVersion(getAppVersion(), "2.2.0") < 0) {
            bankCardService.cardStrategyCheck();
        }
        if ("10".equals(loanReq.getLoanPurpose()) && StringUtils.isBlank(loanReq.getLoanPurposeOther())) {
            return RspMsg.fail(RspEnmu.LOAN_PURPOSE_NULL);
        }
        try {
            // 生成VA
            this.delCustVa(getCustNo());

            boolean newVersion = VersionUtils.compareVersion(getAppVersion(), "2.2.8") >= 0;
            loanApplyService.processLoanReq(loanReq, newVersion);
        } catch (Exception e) {
            log.error("提现提交异常，errMsg = {}", e.getMessage(), e);
            //保存错误日志
            loanOrderErrorLogService.insertLoanOrderErrorLog(loanReq.parseLoanErrLog(getCustNo(), e));
            throw e;
        }
        return RspMsg.ok(200);
    }

    private void delCustVa(String custNo) {
        custVaService.delCustVaForPaystack(custNo, getUserId());
        custVaService.delCustVaForMonnify(custNo);
    }

//    @AppSecurity
////    @RepeatSubmit
//    @PostMapping("/v228/apply")
//    @ApiOperation("提现提交V228")
//    @Log(title = "提现提交V228", businessType = BusinessType.SUBMIT)
//    public RspMsg loanSumbitV228(@RequestBody @Validated ReqMsg reqMsg) {
//
//        LoanReq loanReq = JSON.parseObject(reqMsg.getData().toString(), LoanReq.class);
//        log.info("请求data：{}", JSON.toJSONString(loanReq));
//
//        checkAttribute(loanReq);
//        //一笔在贷
//        if (loanInfoService.isLoanInfoListByInTransit(getCustNo())){
//            throw new BusinessException(RspEnmu.LOAN_APPLY_IS_ALREADY_ON_THE_WAY2);
//        }
//
//        // 验证交易密码
//        checkCustTransPwd(loanReq);
//
//        if ("10".equals(loanReq.getLoanPurpose()) && StringUtils.isBlank(loanReq.getLoanPurposeOther())) {
//            return RspMsg.fail(RspEnmu.LOAN_PURPOSE_NULL);
//        }
//        try {
//            loanService.processLoanReqV228(loanReq);
//        }catch (Exception e){
//            loanService.saveLoanErrorLog(loanReq,e);
//            throw e;
//        }
//        return RspMsg.ok(raiseLimitService.getPromotionJson(getCustNo()));
//    }

    @AppSecurity
    @PostMapping("/apply/test")
    @ApiOperation("提现提交")
    @Log(title = "提现提交", businessType = BusinessType.SUBMIT)
    public RspMsg loanSumbitTest(@RequestBody @Validated ReqMsg reqMsg) {

        PayTrans payTrans = JSON.parseObject(reqMsg.getData().toString(), PayTrans.class);
        log.info("请求data：{}", JSON.toJSONString(payTrans));

        try {
            payTransService.payTrans(payTrans);
        } catch (Exception e) {
            log.error("代付交易处理异常，", e);
            if (e instanceof BusinessException) {
                BusinessException be = (BusinessException) e;
                if (RspEnmu.INSUFFICIENT_ACCOUNT_BALANCE.getCode().equals(be.getCode())) {
//                    updateFrozenAndLoanStatus(loanOrderId, creditAccountId, loanAmt, BizConstants.LOAN_STATUS_2_INSUFFICIENT_ACCOUNT_BALANCE);
//                    sendNotice(appUser, null, BizConstants.SMS_TYPE_BALANCE_INSUFFICIENT);
                    throw be;
                }
            }
        }

        return RspMsg.ok();
    }

    @AppSecurity
    @PostMapping("/cust")
    @ApiOperation("提现账户信息")
    @Log(title = "提现账户信息", businessType = BusinessType.SUBMIT)
    public RspMsg getCustA(@RequestBody @Validated ReqMsg reqMsg) {
        CustAccount custAccount = loanApplyService.getCustAccount();
        return RspMsg.ok(custAccount);
    }

    private void checkCustTransPwd(LoanReq loanReq) {
        JSONObject transJson = new JSONObject();
        transJson.put("userId", getUserId());
        transJson.put("password", loanReq.getTransPwd());
        appService.checkTranPassword(transJson);
    }

    @AppSecurity
    @PostMapping("/trial")
    @ApiOperation("还款试算")
    @Log(title = "还款试算", businessType = BusinessType.GET)
    public RspMsg repaymentTrial(@RequestBody ReqMsg reqMsg) {
        JSONObject dataJson = new JSONObject();
        if (Func.isNotEmpty(reqMsg.getData())) {
            dataJson = JSONObject.parseObject(reqMsg.getData().toString());
        }
        return RspMsg.ok(appService.repaymentTrial(dataJson));
    }

    @AppSecurity
    @PostMapping("/extensionTrial")
    @ApiOperation("延期还款确认页试算")
    @Log(title = "延期还款确认页试算", businessType = BusinessType.GET)
    public RspMsg extensionTrial(@RequestBody ReqMsg reqMsg) {
        JSONObject dataJson = new JSONObject();
        if (Func.isNotEmpty(reqMsg.getData())) {
            dataJson = JSONObject.parseObject(reqMsg.getData().toString());
        }
        // 检查延期包有效性
        boolean canBuy = quickRepayService.checkCanBuyDefer(dataJson.getInteger("deferredId"), dataJson.getString("loanNo"));
        if (!canBuy) {
            throw new BusinessException(RspEnmu.PRODUCT_DEFERRED_IS_DOWN);
        }
        return RspMsg.ok(appService.extensionTrial(dataJson));
    }

    @AppSecurity
    @PostMapping("/preCheck")
    @ApiOperation("贷款提交前检查")
    @Log(title = "贷款提交前检查", businessType = BusinessType.GET)
    public RspMsg preCheck(@RequestBody ReqMsg reqMsg) {
        //是否有Processing，OutStanding的订单
        return RspMsg.ok(!loanInfoService.isLoanInfoListByInTransit(getCustNo()));
    }


    @AppSecurity
    @ApiOperation("获取用户额度")
    @Log(title = "获取用户额度", businessType = BusinessType.FORCE)
    @PostMapping("/getUserQuota")
    public RspMsg getUserQuota(@Validated @RequestBody ReqMsg reqMsg) {
        //参数转换
        JSONObject dataJson = new JSONObject();
        if (null != reqMsg.getData() && StringUtils.isNotBlank(reqMsg.getData().toString())) {
            dataJson = JSONObject.parseObject(reqMsg.getData().toString());
        }

        dataJson.put("userId", getUserId());

        JSONObject userQuota = appService.getUserQuota(dataJson);

        return RspMsg.RspMsgOk(userQuota);
    }

    //
    @AppSecurity
    @ApiOperation("提现校验")
    @Log(title = "提现校验", businessType = BusinessType.FORCE)
    @PostMapping("/checkCanLoan")
    public RspMsg checkCanLoan(@Validated @RequestBody ReqMsg reqMsg) {
        //参数转换
        JSONObject dataJson = new JSONObject();
        if (null != reqMsg.getData() && StringUtils.isNotBlank(reqMsg.getData().toString())) {
            dataJson = JSONObject.parseObject(reqMsg.getData().toString());
        }
        dataJson.put("userId", getUserId());

        JSONObject jsonObject = appService.checkCanLoan(dataJson);

        return RspMsg.RspMsgOk(jsonObject);
    }
}
